package com.xwaf.platform.system.api.entity.pay.wx;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import com.xwaf.platform.common.utils.RandomHelper;

import lombok.Getter;
import lombok.ToString;

@Getter
@ToString
public class WeixinPayReqData {

	private String appid = "";
	private String mch_id = "";
	private String device_info = "";
	private String nonce_str = "";
	private String sign = "";
	private String sign_type = "";
	private String body = "";
	private String detail = "";
	private String attach = "";
	private String out_trade_no = "";
	private String fee_type = "";
	private int total_fee = 0;
	private String spbill_create_ip = "";
	private String time_start = "";
	private String time_expire = "";
	private String goods_tag = "";
	private String notify_url = "";
	private String trade_type = "";
	private String limit_pay = "";
	private String product_id = "";
	private String openid = "";

	/**
	 * 
	 * 
	 * <p>
	 * Default construction method
	 * <p>
	 * 
	 * @author 李聪 <br>
	 * @email xwaf_love@yeah.net <br>
	 * @since JDK 1.8<br>
	 * @date 2019年12月30日 上午8:47:52 <br>
	 * @param appid
	 * @param mchId
	 * @param body
	 *            要支付的商品的描述信息，用户会在支付成功页面里看到这个信息
	 * @param detail
	 *            商品详细信息
	 * @param attach
	 *            支付订单里面可以填的附加数据，API会将提交的这个附加数据原样返回
	 * @param outTradeNo
	 *            商户系统内部的订单号,32个字符内可包含字母, 确保在商户系统唯一
	 * @param feeType
	 *            符合ISO 4217标准的三位字母代码，默认人民币：CNY，其他值列表详见货币类型
	 * @param totalFee
	 *            订单总金额，单位为“分”，只能整数
	 * @param deviceInfo
	 *            商户自己定义的扫码支付终端设备号，方便追溯这笔交易发生在哪台终端设备上
	 * @param spBillCreateIP
	 *            订单生成的机器IP
	 * @param timeStart
	 *            订单生成时间， 格式为yyyyMMddHHmmss，如2009年12 月25 日9 点10 分10
	 *            秒表示为20091225091010。时区为GMT+8 beijing。该时间取自商户服务器
	 * @param timeExpire
	 *            订单失效时间，格式同上
	 * @param goodsTag
	 *            商品标记，微信平台配置的商品标记，用于优惠券或者满减使用
	 * @param notifyUrl
	 *            异步回调地址
	 * @param tradeType
	 *            取值如下：JSAPI，NATIVE，APP
	 * @param productId
	 *            trade_type=NATIVE，此参数必传。此id为二维码中包含的商品ID，商户自行定义
	 * @param limitPay
	 *            no_credit--指定不能使用信用卡支付
	 * @param openId
	 *            trade_type=JSAPI，此参数必传，用户在商户appid下的唯一标识
	 * @param apiKey
	 */
	public WeixinPayReqData(String appid, String mchId, String body, String detail, String attach, String outTradeNo,
			String feeType, int totalFee, String deviceInfo, String spBillCreateIP, String timeStart, String timeExpire,
			String goodsTag, String notifyUrl, String tradeType, String productId, String limitPay, String openId,
			String apiKey) {
		// 微信分配的公众号ID（开通公众号之后可以获取到）
		this.setAppid(appid)
				// 微信支付分配的商户号ID（开通公众号的微信支付功能之后可以获取到）
				.setMch_id(mchId)
				// 要支付的商品的描述信息，用户会在支付成功页面里看到这个信息
				.setBody(body).setDetail(detail)
				// 支付订单里面可以填的附加数据，API会将提交的这个附加数据原样返回，有助于商户自己可以注明该笔消费的具体内容，方便后续的运营和记录
				.setAttach(attach)
				// 商户系统内部的订单号,32个字符内可包含字母, 确保在商户系统唯一
				.setOut_trade_no(outTradeNo).setFee_type(feeType)
				// 订单总金额，单位为“分”，只能整
				.setTotal_fee(totalFee)
				// 商户自己定义的扫码支付终端设备号，方便追溯这笔交易发生在哪台终端设备上
				.setDevice_info(deviceInfo)
				// 订单生成的机器IP
				.setSpbill_create_ip(spBillCreateIP)
				// 订单生成时间， 格式为yyyyMMddHHmmss，如2009年12 月25 日9 点10 分10
				// 秒表示为20091225091010。时区为GMT+8 beijing。该时间取自商户服务器
				.setTime_start(timeStart)
				// 订单失效时间，格式同上
				.setTime_expire(timeExpire)
				// 商品标记，微信平台配置的商品标记，用于优惠券或者满减使用
				.setGoods_tag(goodsTag).setNotify_url(notifyUrl).setTrade_type(tradeType).setProduct_id(productId)
				.setLimit_pay(limitPay).setOpenid(openId)
				// 随机字符串，不长于32 位
				.setNonce_str(RandomHelper.generateRandomCode(32))
				// 把签名数据设置到Sign这个属性中
				.setSign(WeiXinSignature.getSign(toMap(), apiKey));
	}

	public WeixinPayReqData setAppid(String appid) {
		this.appid = appid;
		return this;
	}

	public WeixinPayReqData setMch_id(String mch_id) {
		this.mch_id = mch_id;
		return this;
	}

	public WeixinPayReqData setDevice_info(String device_info) {
		this.device_info = device_info;
		return this;
	}

	public WeixinPayReqData setNonce_str(String nonce_str) {
		this.nonce_str = nonce_str;
		return this;
	}

	public WeixinPayReqData setSign(String sign) {
		this.sign = sign;
		return this;
	}

	public WeixinPayReqData setSign_type(String sign_type) {
		this.sign_type = sign_type;
		return this;
	}

	public WeixinPayReqData setBody(String body) {
		this.body = body;
		return this;
	}

	public WeixinPayReqData setDetail(String detail) {
		this.detail = detail;
		return this;
	}

	public WeixinPayReqData setAttach(String attach) {
		this.attach = attach;
		return this;
	}

	public WeixinPayReqData setOut_trade_no(String out_trade_no) {
		this.out_trade_no = out_trade_no;
		return this;
	}

	public WeixinPayReqData setFee_type(String fee_type) {
		this.fee_type = fee_type;
		return this;
	}

	public WeixinPayReqData setTotal_fee(int total_fee) {
		this.total_fee = total_fee;
		return this;
	}

	public WeixinPayReqData setSpbill_create_ip(String spbill_create_ip) {
		this.spbill_create_ip = spbill_create_ip;
		return this;
	}

	public WeixinPayReqData setTime_start(String time_start) {
		this.time_start = time_start;
		return this;
	}

	public WeixinPayReqData setTime_expire(String time_expire) {
		this.time_expire = time_expire;
		return this;
	}

	public WeixinPayReqData setGoods_tag(String goods_tag) {
		this.goods_tag = goods_tag;
		return this;
	}

	public WeixinPayReqData setNotify_url(String notify_url) {
		this.notify_url = notify_url;
		return this;
	}

	public WeixinPayReqData setTrade_type(String trade_type) {
		this.trade_type = trade_type;
		return this;
	}

	public WeixinPayReqData setProduct_id(String product_id) {
		this.product_id = product_id;
		return this;
	}

	public WeixinPayReqData setLimit_pay(String limit_pay) {
		this.limit_pay = limit_pay;
		return this;
	}

	public WeixinPayReqData setOpenid(String openid) {
		this.openid = openid;
		return this;
	}

	public Map<String, Object> toMap() {
		Map<String, Object> map = new HashMap<String, Object>();
		Field[] fields = this.getClass().getDeclaredFields();
		for (Field field : fields) {
			Object obj;
			try {
				obj = field.get(this);
				if (obj != null) {
					map.put(field.getName(), obj);
				}
			} catch (IllegalArgumentException | IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		System.out.println("微信签名预下单参数：" + map);
		return map;
	}
}
